home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-02-11 | 24.8 KB | 846 lines | [TEXT/PJMM] |
- {****************************************************}
- {}
- { CShApp.p }
- {}
- { Application class for the Showwit application. }
- {}
- {****************************************************}
-
-
- unit CShApp;
-
- interface
-
- uses
- TCL, ShIntf;
-
- implementation
-
- const
- kExtraMasters = 32; (* number of extra master pointer blocks *)
- kRainyDay = 32000; (* total rainy day memory reserve size *)
- kCriticalBalance = 30000; (* portion of rainy day for critical operations *)
- kToolboxBalance = 20000; (* portion of rainy day for toolbox reserve *)
-
- const
- kNumAppHelpMenuItems = 1;
-
- {****************************************************}
- {}
- { IShApp }
- {}
- { Construction of the application object, and initialization of the sounds. }
- { The other initializations are from the Starter project. }
- {}
- {****************************************************}
-
- procedure CShApp.IShApp;
-
- var
- theAppLevelsDirector: CShAppLevelsDirector;
- thePrefsFile: CHandlePrefs;
- theGameDirector: CShGameDirector;
-
- { We have a number of particular sounds to look for, and an }
- { unknown number of flipping sounds. }
- procedure InitSATSounds;
-
- var
- theCounter, theLoadCount: Integer;
- rHandle: Handle;
- rID: Integer;
- rType: ResType;
- rName: Str255;
-
- begin { InitSATSounds }
- SATSoundInit;
-
- { If there are resource errors in the following, the handles are set to nil. }
- { This is a safe condition. }
-
- gSoundGameStarting := Get1Resource('snd ', sndGameStarting);
- gSoundGameComplete := Get1Resource('snd ', sndGameComplete);
- gSoundGameAborted := Get1Resource('snd ', sndGameAborted);
- gSoundNewBestPlayer := Get1Resource('snd ', sndNewBestPlayer);
- gSoundWelcome := Get1Resource('snd ', sndWelcome); { Disposed of early, so load last. }
-
- SetResLoad(FALSE); { Do not need resource, just information. }
-
- gNumFlipSounds := 0;
-
- { Go 1-deep, just into the application resource. }
-
- for theCounter := 1 to Count1Resources('snd ') do begin
- rHandle := Get1IndResource('snd ', theCounter);
- GetResInfo(rHandle, rID, rType, rName);
- if rID >= sndFlipBase then begin
- gNumFlipSounds := gNumFlipSounds + 1;
- end; { if }
- end; { for }
-
- SetResLoad(TRUE);
-
- if gNumFlipSounds > 0 then begin
- gFlipSoundHandles := HandleArrayH(NewHandleCanFail(SizeOf(Handle) * gNumFlipSounds));
- FailNIL(gFlipSoundHandles);
-
- theLoadCount := 1;
- for theCounter := 1 to Count1Resources('snd ') do begin
- rHandle := Get1IndResource('snd ', theCounter);
- GetResInfo(rHandle, rID, rType, rName);
- if rID >= sndFlipBase then begin
- {$PUSH}
- {$R-}
- gFlipSoundHandles^^[theLoadCount] := rHandle;
- {$POP}
- theLoadCount := theLoadCount + 1;
- end; { if }
- end; { for }
- end { if }
- else begin
- gFlipSoundHandles := nil;
- end; { else }
- end; { InitSATSounds }
-
- begin { IShApp }
- itsAppLevelsDirector := nil;
- itsGameDirector := nil;
- itsPrefsFile := nil;
- itsLevelsDoc := nil;
-
- IApplication(kExtraMasters, kRainyDay, kCriticalBalance, kToolboxBalance);
-
- { The parameters to IApplication are the number of times to call MoreMasters, }
- { the number of bytes of heap space to reserve for monitoring }
- { low memory situations, and the credit limit for memory requests. }
- { Four (4) is a reasonable number of MoreMasters calls, }
- { but you should determine a good number for your application }
- { by observing the heap using Lightsbug, }
- { TMON, or Macsbug. Set this parameter to zero, give your }
- { program a rigorous work-out, then look at the heap and count }
- { how many master pointer blocks have been allocated. Master }
- { pointer blocks are nonrelocatable and have a size of $100 }
- { (hex). You should call MoreMasters at least this many }
- { times -- add a few extra just to be safe. The purpose of all }
- { this preflighting is to prevent heap fragmentation. You }
- { don't want the Memory Manager to call MoreMasters and }
- { create a nonrelocatable block in the middle of your heap. By }
- { calling MoreMasters at the very beginning of the program, }
- { you ensure that these blocks are allocated in a group at the }
- { bottom of the heap. }
- { 10 Feb 1996 - Counted 25 such blocks. }
- { The memory reserve is a safeguard for handling low memory }
- { conditions and is used by the GrowMemory method in }
- { CApplication (check there for more comments). In general, }
- { your program should never request a memory block greater }
- { than this reserve size without explicitly checking in }
- { advance whether there is enough free memory to satisfy the }
- { the request. }
- { The credit limit specifies a cut-off level for memory }
- { requests which can tap the memory reserve. Requests larger }
- { than this size will not use the memory reserve when the }
- { system pleads for more memory. }
-
- { Initialize the SAT Sound stuff, and load the sounds which we shall use. }
- { We have to do this here, because the preference file will change the resource.}
-
- InitSATSounds;
-
- { Create the application levels director. }
-
- new(theAppLevelsDirector);
- theAppLevelsDirector.IShAppLevelsDirector(SELF, CurResFile);
- itsAppLevelsDirector := theAppLevelsDirector;
-
- { Now create the preferences file. }
-
- new(thePrefsFile);
- thePrefsFile.IHandlePrefs(STRlistPrefMessages, kSignaturePreferencesFile, TRUE, kNumberOfPrefs);
- itsPrefsFile := thePrefsFile;
-
- { The game director. }
-
- new(theGameDirector);
- itsGameDirector := theGameDirector;
- itsGameDirector.IShGameDirector(SELF);
- end; { IShApp }
-
-
- {****************************************************}
- {}
- { MakeBartender }
- {}
- { Build a bartender which can handle the application help menu. }
- {}
- {****************************************************}
-
- procedure CShApp.MakeBartender;
-
- var
- theBartenderHM: CBartenderHelpMenu;
-
- begin { MakeBartender }
- new(theBartenderHM);
- gBartender := theBartenderHM;
- theBartenderHM.IBartenderHelpMenu(MBARapp);
- end; { MakeBartender }
-
-
- {****************************************************}
- {}
- { SetUpFileParameters }
- {}
- { Recognized file types and the application signature. }
- {}
- {****************************************************}
-
- procedure CShApp.SetUpFileParameters;
-
- begin { SetUpFileParameters }
- inherited SetUpFileParameters; { Be sure to call the default method }
-
- { sfNumTypes is the number of file types your application knows about. }
- { sfFileTypes[] is an array of file types. }
- { You can define up to 4 file types in sfFileTypes[]. }
-
- { The application knows about both levels and it preferences file. }
- { However we don't want to be able to open the preferences file }
- { from the Open… dialog. }
- sfNumTypes := 1;
- sfFileTypes[0] := kSignatureLevelsFiles;
-
- { We still have to check elsewhere for filetype, since we want to }
- { be able to context switch (from the Finder) if we double click }
- { on the preferences file. }
-
- { Although it's not an instance variable, this method is a good place to set the}
- { gSignature global variable. Set this global to your application 's signature. }
- { You' ll use it to create a file (see CFile.CreateNew). }
-
- gSignature := kSignatureApplication;
- end; { SetUpFileParameters }
-
-
- {****************************************************}
- {}
- { SetUpMenus }
- {}
- { Insert the items into the application help menu. }
- {}
- {****************************************************}
-
- procedure CShApp.SetUpMenus;
-
- begin { SetUpMenus }
- inherited SetUpMenus;
- CBartenderHelpMenu(gBartender).AddHelpMenuItems(STRlistAppHelpMenu, kNumAppHelpMenuItems);
- end; { SetUpMenus }
-
-
- {****************************************************}
- {}
- { DoCommand }
- {}
- { The application is responsible for calling up the about/help dialog, }
- { for calling the default levels reader, and for communicating with }
- { the levels document or preferences file about the best players. }
- {}
- {****************************************************}
-
- procedure CShApp.DoCommand (theCommand: longint);
-
- { Create and call the about/help director with the appropriate first screen. }
- procedure DoAboutAndHelp;
-
- var
- theAboutDirector: CShHelpDirector;
-
- begin { DoAbout }
- new(theAboutDirector);
- theAboutDirector.IShHelpDirector(SELF);
- if theCommand = cmdAbout then begin
- theAboutDirector.DoAboutAndHelp(AboutScreen);
- end { if }
- else begin
- theAboutDirector.DoAboutAndHelp(HelpScreen);
- end; { else }
- ForgetObject(theAboutDirector);
- end; { DoAbout }
-
- { If there is no active levels document, clear the preferences file. }
- { Otherwise call the active document. }
- procedure DoClearBestPlayers;
-
- begin { DoClearBestPlayers }
- if itsLevelsDoc = nil then begin
- itsPrefsFile.SetPref(kPrefBestPlayers, nil);
- itsPrefsFile.SetPref(kPrefNumBest, nil);
- end { if }
- else begin
- itsLevelsDoc.ClearBestPlayers;
- end; { else }
- end; { DoClearBestPlayers }
-
- begin { DoCommand }
- case theCommand of
-
- cmdAbout, cmdHelp: begin
- DoAboutAndHelp;
- end; { cmdAbout, cmdHelp }
-
- cmdReadDefLevels: begin
- ReadDefaultLevels;
- end; { cmdReadDefLevels }
-
- cmdClearBestPlayers: begin
- { Upon entry, the game director will have already cleared it from its visible levels. }
- { Now update the document/ pref file. }
- DoClearBestPlayers;
- end; { cmdClearBestPlayers }
-
- otherwise begin
- inherited DoCommand(theCommand);
- end; { otherwise }
- end; { case }
- end; { DoCommand }
-
-
- {****************************************************}
- {}
- { DoAppleEvent }
- {}
- { Handle the core apple events. The way in which we do so is }
- { different to that for a conventional application. }
- {}
- {****************************************************}
-
- procedure CShApp.DoAppleEvent (anAppleEvent: CAppleEvent);
-
- var
- eventClass: DescType;
- eventID: DescType;
- err: Integer;
-
- begin { DoAppleEvent }
- eventClass := anAppleEvent.GetEventClass;
- eventID := DescType(anAppleEvent.GetEventID);
-
- if eventClass = kCoreEventClass then begin
- if eventID = kAEOpenApplication then begin
- DoOpenAppEvent(anAppleEvent);
- end { if }
- else if eventID = kAEOpenDocuments then begin
- DoOpenOrPrintDocEvent(anAppleEvent);
- end { else if }
- else if eventID = kAEQuitApplication then begin
- if anAppleEvent.GotRequiredParams then begin
- err := anAppleEvent.RequestInteraction(MAXLONGINT);
- end; { if }
- if err = noErr then begin
- if Quit then begin
- end; { if }
- (* if we're still running then Quit didn't succeed *)
- (* but we don't know what error to report! *)
-
- anAppleEvent.SetErrorResult(err);
- end; { if }
- end { else if }
- else begin
- { Don't know how to handle any other kind of core event. }
- { No printing, or publish and subscribe! :) }
- anAppleEvent.SetErrorResult(errAEEventNotHandled);
- end; { else }
- end; { if }
-
- end; { DoAppleEvent }
-
-
- {****************************************************}
- {}
- { DoOpenAppEvent }
- {}
- { Handle the kAEOpenApplication AppleEvent, by loading the default }
- { levels. }
- {}
- {****************************************************}
-
- procedure CShApp.DoOpenAppEvent (anAppleEvent: CAppleEvent);
-
- var
- ignore: Integer;
-
- begin { DoOpenWithNoDocs }
- { We ignore any attempts to read in levels if we are playing a game. }
- { This might happen, for instance, if we switch to the Finder and }
- { double click on application icon. }
- if GameDirector.IsPlaying then begin
- PositionDialog('ALRT', ALRTGamePlayingSoCannotOpen);
- InitCursor;
- ignore := NoteAlert(ALRTGamePlayingSoCannotOpen, nil);
- end { if }
- else begin
- { Upon opening, with no other documents, load the default levels. }
- if anAppleEvent.GotRequiredParams then begin
- SetCursor(gWatchCursor^^);
-
- ReadDefaultLevels;
- anAppleEvent.SetErrorResult(noErr);
- end; { if }
- end; { else }
- end; { DoOpenAppEvent }
-
-
- {****************************************************}
- {}
- { DoOpenOrPrintDocEvent }
- {}
- { Handle the kAEOpenDocuments AppleEvent, by the loading the first }
- { of any levels files. We only load the first, because only one file }
- { is open at any time. }
- {}
- {****************************************************}
-
- procedure CShApp.DoOpenOrPrintDocEvent (theEvent: CAppleEvent);
-
- var
- ignore: Integer;
-
- docList: CArray;
- numDocs: Longint;
- currDoc: FSSpec;
- eventID: DescType;
- fi: FailInfo;
- wdRefNum: Integer;
- reply: SFReply;
- fileInfo: FInfo;
-
- theCounter: LongInt;
- foundLevelsFile: Boolean;
-
- procedure AEExceptionHandler (error: Integer;
- message: Longint);
-
- begin { AEExceptionHandler }
- ForgetObject(docList);
- end; { AEExceptionHandler }
-
- begin { DoOpenOrPrintDocEvent }
- { We ignore any attempts to read in levels if we are playing a game. }
- { This might happen, for instance, if we switch to the Finder and }
- { double click on some levels files. }
- if GameDirector.IsPlaying then begin
- PositionDialog('ALRT', ALRTGamePlayingSoCannotOpen);
- InitCursor;
- ignore := NoteAlert(ALRTGamePlayingSoCannotOpen, nil);
- end { if }
- else begin
- docList := nil;
- CatchFailures(fi, AEExceptionHandler);
-
- SetCursor(gWatchCursor^^);
-
- docList := theEvent.ExtractFromDescList(keyDirectObject, typeFSS, SIZEOF(FSSpec));
- if theEvent.GotRequiredParams then begin
- eventID := theEvent.GetEventID;
- numDocs := docList.GetNumItems;
-
- theCounter := 1;
- foundLevelsFile := FALSE;
- while (theCounter <= numDocs) and not foundLevelsFile do begin
- docList.GetItem(@currDoc, theCounter);
- FailOSErr(OpenWD(currDoc.vRefNum, currDoc.parID, Longint(gSignature), wdRefNum));
- FailOSErr(FSpGetFInfo(currDoc, fileInfo));
-
- if fileInfo.fdType = kSignatureLevelsFiles then begin
- reply.good := TRUE;
- reply.vRefNum := wdRefNum;
- reply.fType := fileInfo.fdType;
- reply.version := 0;
- reply.copy := FALSE;
- reply.fName := currDoc.name;
-
- OpenDocument(reply);
-
- foundLevelsFile := TRUE;
- end { if }
- else begin
- theCounter := theCounter + 1;
- end; { else }
- end; { while }
-
- if not foundLevelsFile then begin
- { This could happen if you launch the application by opening the preferences file. }
- ReadDefaultLevels;
- end; { if }
-
- (* event was handled successfully*)
-
- theEvent.SetErrorResult(noErr);
- ForgetObject(docList);
- Success;
- end; { if }
- end; { else }
- end; { DoOpenOrPrintDocEvent }
-
-
- {****************************************************}
- {}
- { UpdateMenus }
- {}
- { The application is responsible for file commands, including the use of default }
- { levels. It also handles the help command. }
- {}
- {****************************************************}
-
- procedure CShApp.UpdateMenus;
-
- begin { UpdateMenus }
- inherited UpdateMenus;
-
- { We could make the game director responsible for deactivating the Open… }
- { or Use Default Levels commands, based on whether it is playing, however }
- { activation of the Open… command is the responsibility of the application, }
- { and is performed in the inherited method. }
-
- if GameDirector.IsPlaying then begin
- gBartender.DisableCmd(cmdOpen);
- end { if }
- else begin
- if itsLevelsDoc <> nil then begin
- gBartender.EnableCmd(cmdReadDefLevels);
- end; { else }
- end; { else }
-
- { The help command is always available. }
- gBartender.EnableCmd(cmdHelp);
- end; { UpdateMenus }
-
-
- {****************************************************}
- {}
- { Preload }
- {}
- { Loads the first of any preloaded levels files, then call StartUpAction. }
- { We only load the first, because only one file is open at any time. }
- {}
- {****************************************************}
-
- procedure CShApp.Preload;
-
- var
- openOrPrint: Integer; { Type of action requested. }
- numPreloads: Integer; { No. of files to process. }
- macAppFile: AppFile; { Info about file. }
- macSFReply: SFReply; { Standard File info record. }
-
- theCounter: Integer;
- foundLevelsFile: Boolean;
-
- begin { Preload }
- CountAppFiles(openOrPrint, numPreloads);
-
- if numPreloads > 0 then begin
-
- SetCursor(gWatchCursor^^);
-
- { Scan the preload candidates for a levels file. }
- { Remember that we must ignore the preferences file. }
- theCounter := 1;
- foundLevelsFile := FALSE;
- while (theCounter <= numPreloads) and not foundLevelsFile do begin
- { Get info about the file. }
- GetAppFiles(theCounter, macAppFile);
-
- if macAppFile.fType = kSignatureLevelsFiles then begin
-
- { Copy information into our record. }
- macSFReply.fType := macAppFile.fType;
- macSFReply.vRefNum := macAppFile.vRefNum;
- macSFReply.version := macAppFile.versNum;
- macSFReply.fName := macAppFile.fName;
-
- OpenDocument(macSFReply);
-
- foundLevelsFile := TRUE;
- end { if }
- else begin
- theCounter := theCounter + 1;
- end; { else }
- end; { while }
-
- if not foundLevelsFile then begin
- { Set the count to zero, so that we know to open the default levels. }
- numPreloads := 0;
- end; { if }
-
- { Now tell the Finder that we're done. }
-
- for theCounter := 1 to numPreloads do begin
- ClrAppFiles(theCounter);
- end; { for }
-
- end; { if }
-
- StartUpAction(numPreloads);
- end; { Preload }
-
-
- {****************************************************}
- {}
- { StartUpAction }
- {}
- { If there were no preloaded files, load the default levels. }
- {}
- {****************************************************}
-
- procedure CShApp.StartUpAction (numPreloads: Integer);
-
- var
- waitForOAPP: Boolean;
-
- begin { StartupAction }
- FlushEvents(everyEvent, 0);
-
- (* Only read the default levels if there are no AppleEvents.*)
- (* If there are, we anticipate getting the open app event*)
- (* Under the THINK Pascal environment, we don't get an *)
- (* initial oapp. We use the compiler variable TCL_DEBUG *)
- (* to determine if we're running the debug version. *)
- (* If we are, we don't wait for the oapp event. *)
-
- waitForOAPP := gSystem.hasAppleEvents;
-
- {$IFC TCL_DEBUG}
- waitForOAPP := FALSE;
- {$ENDC}
-
- if (not waitForOAPP) and (numPreloads = 0) then begin
- SetCursor(gWatchCursor^^);
-
- ReadDefaultLevels;
- end; { if }
-
- { The game director's screen is updated, either by the ReadDefaultLevels call, }
- { or by the document sending a screen update message. }
- end; { StartupAction }
-
-
- {****************************************************}
- {}
- { ExitApp }
- {}
- { We set our pointers to nil before exiting the application. The objects }
- { to which they were pointing will be disposed of in inherited methods . }
- { Also dispose of the sounds and close the preferences file. }
- {}
- {****************************************************}
-
- procedure CShApp.ExitApp;
-
- { Shut up the sounds which are playing, then dispose of them. }
- procedure DisposeSATSounds;
-
- var
- theCounter: Integer;
-
- begin { DisposeSATSounds }
- SATSoundShutup;
-
- if gFlipSoundHandles <> nil then begin
- for theCounter := 1 to gNumFlipSounds do begin
- {$PUSH}
- {$R-}
- SATDisposeSound(gFlipSoundHandles^^[theCounter]);
- gFlipSoundHandles^^[theCounter] := nil;
- {$POP}
- end; { for }
- ForgetHandle(gFlipSoundHandles);
- gFlipSoundHandles := nil;
- end; { if }
-
- { The welcoming sound was disposed of after it was first played. }
-
- SATDisposeSound(gSoundGameStarting);
- gSoundGameStarting := nil;
- SATDisposeSound(gSoundGameComplete);
- gSoundGameComplete := nil;
- SATDisposeSound(gSoundGameAborted);
- gSoundGameAborted := nil;
- SATDisposeSound(gSoundNewBestPlayer);
- gSoundNewBestPlayer := nil;
- end; { DisposeSATSounds }
-
- begin { ExitApp }
- { Stop SAT sounds. }
- DisposeSATSounds;
-
- { Close the preferences file. }
-
- itsPrefsFile.Free;
- itsPrefsFile := nil;
-
- { Because the application levels director, the game director and level documents }
- { are installed in the supervision heirarchy, the default methods handle disposal. }
- { All we need to do is reset our own pointers. }
-
- itsAppLevelsDirector := nil;
- itsGameDirector := nil;
- itsLevelsDoc := nil;
-
- inherited ExitApp;
- end; { ExitApp }
-
-
- {****************************************************}
- {}
- { OpenDocument }
- {}
- { Opens the given levels document. If a previous document is open, }
- { it needs to be closed first. }
- {}
- {****************************************************}
-
- procedure CShApp.OpenDocument (macSFReply: SFReply);
-
- var
- theDocument: CShLevelsDoc;
- fi: FailInfo;
-
- { If something goes wrong, dispose of the document }
- { and let the failure propagate. }
- procedure HandleFailure (error: Integer;
- message: Longint);
-
- begin { HandleFailure }
- ForgetObject(theDocument);
- end; { HandleFailure }
-
- begin { OpenDocument }
- theDocument := nil;
-
- if itsLevelsDoc <> nil then begin
-
- { If we have a levels document open already, then close it. }
-
- itsLevelsDoc.DoCommand(cmdClose);
- itsLevelsDoc := nil;
- end;
-
- CatchFailures(fi, HandleFailure);
-
- new(theDocument);
- theDocument.IShLevelsDoc(SELF);
- theDocument.OpenFile(macSFReply);
-
- itsLevelsDoc := theDocument;
-
- Success;
-
- { The game director's screen has to be updated. Note that we only }
- { allow files to be open at the title screen, not while a game is being played. }
-
- itsGameDirector.DisplayTitleScreen(FALSE);
- end; { OpenDocument }
-
-
- {****************************************************}
- {}
- { GameDirector }
- {}
- { Returns the director of the main game window. This is to allow documents to }
- { send the list of levels to the game director. }
- {}
- {****************************************************}
-
- function CShApp.GameDirector: CShGameDirector;
-
- begin { GameDirector }
- GameDirector := itsGameDirector;
- end; { GameDirector }
-
-
- {****************************************************}
- {}
- { PreferencesFile }
- {}
- { Returns the preferences file object. This allows access by both the }
- { application and the reader of the default application levels. }
- {}
- {****************************************************}
-
- function CShApp.PreferencesFile: CHandlePrefs;
-
- begin { GameDirector }
- PreferencesFile := itsPrefsFile;
- end; { GameDirector }
-
-
- {****************************************************}
- {}
- { ReadDefaultLevels }
- {}
- { The default levels have been read from the application resource, and sent }
- { to the game director. This is called at startup if necessary, or as a menu }
- { command. }
- {}
- {****************************************************}
-
- procedure CShApp.ReadDefaultLevels;
-
- begin { ReadDefaultLevels }
- if itsLevelsDoc <> nil then begin
-
- { If we have a levels document open already, then close it. }
- { Note that here we have to nil the pointer, ready for opening }
- { another document. }
-
- itsLevelsDoc.DoCommand(cmdClose);
- itsLevelsDoc := nil;
- end; { if }
-
- if itsAppLevelsDirector.GetWindow = nil then begin
- itsAppLevelsDirector.BuildWindow;
- end { if }
- else begin
- itsAppLevelsDirector.GetWindow.Show;
- end; { else }
-
- itsGameDirector.SetLevels(itsAppLevelsDirector.AppLevels);
-
- { Bring the game director's window to the front. Then hide our reader. }
- { The order is important! }
-
- itsGameDirector.GetWindow.Select;
- itsAppLevelsDirector.GetWindow.Hide;
-
- { The game director's screen has to be updated. }
-
- itsGameDirector.DisplayTitleScreen(FALSE);
- end; { ReadDefaultLevels }
-
-
- {****************************************************}
- {}
- { StoreBestPlayer }
- {}
- { Tells the application levels director, or the active document, to store the }
- { best player. }
- {}
- {****************************************************}
-
- procedure CShApp.StoreBestPlayer (aLevelNum: LevelsRange;
- aPlayer: Str15;
- aMoves: Integer;
- aTime: LongInt);
-
- begin { StoreBestPlayer }
- if itsLevelsDoc = nil then begin
- itsAppLevelsDirector.StoreBestPlayer(aLevelNum, aPlayer, aMoves, aTime);
- end { if }
- else begin
- itsLevelsDoc.StoreBestPlayer(aLevelNum, aPlayer, aMoves, aTime);
- end; { else }
- end; { StoreBestPlayer }
-
-
- end. { CShApp }